/*---------------------------------------------------------------
 * Confidential and Proprietary
 * Copyright 2006 CMO & Hewlett-Packard Development Company, L.P.
 * All Rights Reserved
 *---------------------------------------------------------------
 * Project Name    : SPF
 * Sub Project Name: SPF
 *
 * Class Name      : PropertiesObject
 * Purpose         : Base properties object.
 *---------------------------------------------------------------
 * Modification Log
 * Date         Ver. #      Programmer       Description
 *
 * 2006-03-10    1.0         Zhang Minjin     transfer from cmo mis2   
 *---------------------------------------------------------------
 */

package com.erdos.common.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.erdos.common.exception.ServiceException;


/**
 * @author cwtu
 * 
 * com.hp.common.util
 * 
 * AbstractFactory extends PropertiesObject
 * 
 * public static Object getInstance(String factoryAlias)
 * 
 * String factoryAlias = "DMSDaoFactory"; String factoryAlias =
 * "DMSServiceFactory";
 * 
 * [AbstractFactory.properties] (global properties file)
 * abstractfactory.DMSDaoFactory.class.name=com.cmo.dms.model.impl.OJBDaoFactory
 * abstractfactory.DMSServiceFactory.class.name=com.cmo.dms.service.impl.JavaServiceFactory
 * #abstractfactory.DMSServiceFactory.class.name=com.cmo.dms.service.ejb.EJBServiceFactory
 * #abstractfactory.DMSEJBServiceFactory.class.name=com.cmo.dms.service.ejb.EJBServiceFactory
 * 
 * 
 * <YourEJBServiceFactory>extends AbstractEBServiceFactoryImpl implements
 * <YourServiceFactory>
 * 
 * [Client Usage]
 * 
 * ((DaoFactory) AbstractFactory.getInstnace("DMSDaoFactory")).getXXXDao();
 * ((SerivceFactory)
 * AbstractFactory.getInstnace("DMSServiceFactory")).getXXXService();
 * 
 * GlobalSettings extends PropertiesObject [GlobalSettings.properties]
 * getDaoFactoryAlias() : String getSMTPHost() : getDebugMode() : ...
 *  
 */
public abstract class PropertiesObject {
	private final Log logger = LogFactory.getLog(this.getClass());
	
	public abstract String getPropertiesAlias();

	private Properties props;

	private boolean isCached = true;

	public synchronized Properties getProperties() {
		//		Properties props = null;
		//		Properties parentProps = null;
		//				
		//		if(getPropertiesAlias() == null) throw new
		// Exception("PROPERTIES_ALIAS not specified");
		//		
		//		Vector classes = new Vector();
		//		
		//		Class clazz = getClass();
		//		while(clazz != null)
		//		{
		//			classes.add(clazz);
		//			clazz = clazz.getSuperclass();
		//		}
		//		
		//		for(int i = classes.size() - 1; i >= 0; i --)
		//		{
		//			try
		//			{
		//				parentProps = getProperties((Class) classes.get(i),
		// getPropertiesAlias(), isCached);
		//				if(parentProps != null)
		//				{
		//					if(props == null)
		//					{
		//						props = new Properties();
		//					}
		//					props.putAll(parentProps);
		//				}
		//			}
		//			catch(Exception e)
		//			{
		//				System.out.println("[PropertiesObject.getProperties] [INFO] load
		// properties error : " + e.getMessage());
		//			}
		//		}
		//
		//		if(props != null)
		//		{
		//			String cacheEnabled =
		// props.getProperty("propertiesobject.cache.enabled");
		//			if("false".equals(cacheEnabled))
		//			{
		//				isCached = false;
		//			}
		//			else
		//			{
		//				isCached = true;
		//			}
		//		}
		//			
		//		System.out.println("[PropertiesObject.getProperties] PROPERTIES=" +
		// props);

		if (getPropertiesAlias() == null)
			throw new ServiceException("PROPERTIES_ALIAS not specified");

		if (props == null || !isCached) {
			//			System.out.println("[PropertiesObject.getProperties] CLASS=" +
			// getClass().getName() + " ALIAS=" + getPropertiesAlias() + "
			// CACHED=" + isCached);

			props = new Properties();

			//			InputStream in =
			// getClass().getResourceAsStream(getPropertiesAlias());
			//			if(in == null || in.available() == 0)
			//			{
			//				in =
			// getClass().getSuperclass().getResourceAsStream(getPropertiesAlias());
			//			}

			InputStream in = null;

			Class clazz = getClass();
			while (clazz != null && !Object.class.equals(clazz) && in == null) {
				if (PropertiesObject.class.equals(clazz)) {
					in = ClassLoader
							.getSystemResourceAsStream(getPropertiesAlias());
				} else {
					in = clazz.getResourceAsStream(getPropertiesAlias());
				}

				String infoMsg = null;
				if (in != null) {
					infoMsg = "[FOUND]";
				} else {
					infoMsg = "[NOT FOUND]";
				}
				logger.debug(infoMsg);
				clazz = clazz.getSuperclass();
			}
			try {
				props.load(in);
				in.close();
			} catch (IOException ioe) {
				logger.error(MsgFormat.format(
						AppConstants.LOG_PREFIX_BASE_ERROR,
						"Error getProperties", getPropertiesAlias()), ioe);
				throw new ServiceException(ioe);
			}

			String cacheEnabled = props
					.getProperty("propertiesobject.cache.enabled");
			if ("false".equals(cacheEnabled)) {
				isCached = false;
			} else {
				isCached = true;
			}

			System.out.println("[PropertiesObject.getProperties] PROPERTIES="
					+ props);
		}

		return props;
	}

	public String getProperty(String propName) throws ServiceException {
		return getProperties().getProperty(propName);
	}

	public void reset() {
		//		PROPERTIES_MAP.clear();
		props = null;
	}
}
